<?php


abstract class ConceptionsCollection {

    private static $state = true;
    private static $initialized = false;

    private static $items = array();
    private static $rows = array();
    private static $rowsById = array();
    private static $rowsReaded = false;





    private static function readRows() {
        if(self::$rowsReaded) return true;


        $query = "SELECT * FROM views_conception_list ORDER BY priority, id ASC";
        $res = DB::query($query);
        if (!DB::$lastReqState) return false;

        while ($row = $res->fetch_array(MYSQLI_ASSOC)){
            self::$rows[] = $row;
            self::$rowsById[$row['id']] = $row;
        }
        self::$rowsReaded = true;
        return true;
    }



    private static function reset() {
        self::$state = true;
        self::$initialized = false;
        self::$rowsReaded = false;
        self::$rows = array();
        self::$items = array();
    }



    public static function Init($reset = false) {
        if ($reset) self::reset ();
        if (!self::$state) return false;

        if(self::$initialized) return true;
        if(!self::readRows()) return false;
        self::$items = self::setConceptions();

        foreach(self::$items as $c) $c->init();
        self::$initialized = true;
        return true;
    }


    private static function setConceptions() {
        $items = array();
        $children = array();

        foreach (self::$rows as $row) {
            $conception = new RPConception($row);
            if ($conception->parent_id) $children[] = $conception;
            else $items[$conception->id] = $conception;
        }

        foreach ($children as $conception) {
            if (Arr::getValue($items, $conception->parent_id, false)) $items[$conception->parent_id]->addChild($conception);
        }

        return $items;
    }



    public static function storeObject($obj) {
        if(!self::$state) return;

        foreach (self::$items as &$item) {
            if ($item->storeObject($obj)) return;
        }
    }






    public static function getConceptionById($id) {
        $parent = Arr::getValue(self::$items, $id, false);
        if ($parent) return $parent;

        foreach (self::$items as $parent) {
            $c = Arr::getValue($parent->children, $id, false);
            if ($c) return $c;
        }
        return false;
    }





    public static function allSorted() {
        return self::Init()?  self::$items : array();
    }


    public static function allRowsById() {
        return self::Init()?  self::$rowsById : array();
    }
}






















class RPConception {
    public $id;
    public $name;
    public $parent_id;
    public $priority;

    public $children = array();

    private $otherProperties = array();
    public $objects = array();




    function __construct($carray) {
        if (!is_array($carray)) return;

        foreach ($carray as $key => $val)  {
            $this->$key = $val;
        }
    }

    public function __set($name, $value) {
        $this->otherProperties[$name] = $value;
    }

    public function __get($name) {
        return Arr::getValue($this->otherProperties, $name, '');
    }


    public function addChild($conception) {
        if (! $conception instanceof RPConception) return;
        $this->children[$conception->id] = $conception;
    }

    public function hasChild() {
        return (count($this->children)>0);
    }



    public function init() {
        // do something to init...

        if ($this->hasChild()) foreach ($this->children as $c) $c->init();
    }


    public function storeObject($obj) {
        $c  = Arr::getValue($obj, 'conception', false);
        $id = Arr::getValue($obj, 'id', FALSE);
        if (!$c) return false;

        if (!$this->hasChild()) {
            if ($c == $this->id) {
                $this->objects[$id] = $obj;
                return true;
            }
            return false;
        }
        else {
            if (array_key_exists($c, $this->children)) return $this->children[$c]->storeObject($obj);
            else return false;
        }
    }




}



?>